﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SnapLib
{
   public class Heap
   {
      internal Heap(IntPtr handle)
      {
      }

      [Flags]
      internal enum PROCESS_HEAP_ENTRY_WFLAGS : ushort
      {
         PROCESS_HEAP_ENTRY_BUSY = 0x0004,
         PROCESS_HEAP_ENTRY_DDESHARE = 0x0020,
         PROCESS_HEAP_ENTRY_MOVEABLE = 0x0010,
         PROCESS_HEAP_REGION = 0x0001,
         PROCESS_HEAP_UNCOMMITTED_RANGE = 0x0002,
      }


      [StructLayoutAttribute(LayoutKind.Explicit)]
      internal struct UNION_BLOCK
      {
         [FieldOffset(0)]
         public STRUCT_BLOCK Block;

         [FieldOffset(0)]
         public STRUCT_REGION Region;
      }

      [StructLayoutAttribute(LayoutKind.Sequential)]
      internal struct STRUCT_BLOCK
      {
         public IntPtr hMem;
         public uint dwReserved1_1;
         public uint dwReserved1_2;
         public uint dwReserved1_3;
      }

      [StructLayoutAttribute(LayoutKind.Sequential)]
      internal struct STRUCT_REGION
      {
         public uint dwCommittedSize;
         public uint dwUnCommittedSize;
         public IntPtr lpFirstBlock;
         public IntPtr lpLastBlock;
      }

      [StructLayoutAttribute(LayoutKind.Sequential)]
      internal struct PROCESS_HEAP_ENTRY
      {
         public IntPtr lpData;
         public uint cbData;
         public byte cbOverhead;
         public byte iRegionIndex;
         public PROCESS_HEAP_ENTRY_WFLAGS wFlags;
         public UNION_BLOCK UnionBlock;
      }

      [Flags]
      internal enum HeapCompactFlags : uint
      {
         HEAP_NO_FLAGS_ZERO = 0x00000000,
         HEAP_NO_SERIALIZE = 0x00000001
      }

      [Flags]
      internal enum HeapValidateFlags : uint
      {
         HEAP_NO_FLAGS_ZERO = 0x00000000,
         HEAP_NO_SERIALIZE = 0x00000001
      }

      [Flags]
      internal enum HeapFreeFlags : uint
      {
         HEAP_NO_FLAGS_ZERO = 0x00000000,
         HEAP_NO_SERIALIZE = 0x00000001
      }

      [Flags]
      internal enum HeapAllocFlags : uint
      {
         HEAP_NO_FLAGS_ZERO = 0x00000000,
         HEAP_GENERATE_EXCEPTIONS = 0x00000004,
         HEAP_NO_SERIALIZE = 0x00000001,
         HEAP_ZERO_MEMORY = 0x00000008
      }

      [DllImport("kernel32.dll", SetLastError = true)]
      internal static extern IntPtr GetProcessHeap();

      [DllImport("kernel32.dll", SetLastError = true)]
      internal static extern uint GetProcessHeaps(uint NumberOfHeaps, IntPtr[] ProcessHeaps);

      [DllImport("kernel32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      internal static extern bool HeapWalk(IntPtr hHeap, ref PROCESS_HEAP_ENTRY lpEntry);
   }
}
